﻿ #region Disclaimer/Info
 
 /////////////////////////////////////////////////////////////////////////////////////////////////
 //
 //   File:		IPostService.cs
 //   Website:		http://dexterblogengine.com/
 //   Authors:		http://dexterblogengine.com/About.ashx
 //   Rev:		1
 //   Created:		19/01/2011
 //   Last edit:		19/01/2011
 //   License:		GNU Library General Public License (LGPL)
 //   File:            IPostService.cs
 //   For updated news and information please visit http://dexterblogengine.com/
 //   Dexter is hosted to Codeplex at http://dexterblogengine.codeplex.com
 //   For any question contact info@dexterblogengine.com
 //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #endregion
 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Dexter.Core.EventArgs;
using Dexter.DataTransferObject;
using Dexter.Domain.Model;
using Dexter.Domain.Results;

namespace Dexter.Services {
	/// <summary>
	/// 	Rapresents the gateway for all service to save, retrieve and manipulate data for <see cref="Post"/>.
	/// </summary>
	public interface IPostService : IDomainService {
		///<summary>
		///	Retrieve the list of months for all published posts.
		///</summary>
		///<returns>
		///	Return a list of <c>MonthDTO</c> based on <c>PublishDate</c> property of <c>Item</c>.
		///	It could be null if there aren't items into the repository.
		///</returns>
		IList<Month> GetMonths();

		///<summary>
		///	Retrieve a post for a specified key.
		///</summary>
		///<param name = "key">The key of the post.</param>
		///<returns>
		///	An instance of <see cref="Post"/>.
		///	It could be null if there isn't an item with the specified key into the repository.
		///</returns>
		/// <remarks>
		///	The object result will be returned with tracking disabled. Pay attetion, or use the overload with enableTracking parameter.
		/// </remarks>
		Post GetByKey ( int key );

		///<summary>
		///	Retrieve a post for a specified key.
		///</summary>
		///<param name = "key">The key of the post.</param>
		///<returns>
		///	An instance of <see cref="PostDto"/>.
		///	It could be null if there isn't an item with the specified key into the repository.
		///</returns>
		/// <remarks>
		///	The object result will be returned with tracking disabled. Pay attetion, or use the overload with enableTracking parameter.
		/// </remarks>
		PostDto GetPostDtoByKey ( int key );

		///<summary>
		///	Retrieve a post for a specified slug.
		///</summary>
		///<param name = "slug">The slug.</param>
		///<returns>
		///	An instance of <see cref="Post"/>.
		///	It could be null if there isn't an item with the specified slug into the repository.
		///</returns>
		Post GetBySlug ( string slug );

		///<summary>
		///	Retrieve a post for a specified slug.
		///</summary>
		///<param name = "slug">The slug.</param>
		///<returns>
		///	An instance of <see cref="PostDto"/>.
		///	It could be null if there isn't an item with the specified slug into the repository.
		///</returns>
		PostDto GetPostDtoBySlug ( string slug );

		/// <summary>
		/// 	Deletes the post with the specified key, from the repository.
		/// </summary>
		/// <param name = "key">The key.</param>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="key"/> is lesser than 1.</exception>
		///<exception cref="PostNotFoundException"> If the <see cref="Post"/> will not found into the repository.</exception>
		void Delete ( int key );

		/// <summary>
		/// 	Saves the specified post into the repository.
		/// </summary>
		/// <param name = "item">The item.</param>
		void Save ( Post item );

		/// <summary>
		/// 	Updates the specified post into the repository.
		/// </summary>
		/// <param name = "item">The item.</param>
		void Update ( Post item );

		///<summary>
		///	Retireve a paged list of all posts with the property <see cref="Item.CommentEnabled"/> set to <c>false</c>.
		///</summary>
		/// <remarks>
		///		The result will include only published past posts.
		///		Moreover the result hasn't the tracking system enabled
		/// </remarks>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<Post> GetPublishedPostWithCommentsDisabled ( int pageIndex, int pageSize );

		///<summary>
		///	Retireve a paged list of all posts with the property <see cref="Item.CommentEnabled"/> set to <c>false</c>.
		///</summary>
		/// <remarks>
		///		The result will include only published past posts.
		///		Moreover the result hasn't the tracking system enabled
		/// </remarks>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<PostDto> GetPublishedPostDtoWithCommentsDisabled ( int pageIndex, int pageSize );

		///<summary>
		///	Retireve a paged list of all posts.
		///</summary>
		/// <remarks>
		///		The result will include published, unpublished, future and past posts.
		///		Moreover the result hasn't the tracking system enabled
		/// </remarks>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<Post> GetCompleteList ( int pageIndex, int pageSize );

		///<summary>
		///	Retireve a paged list of all posts.
		///</summary>
		/// <remarks>
		///		The result will include published, unpublished, future and past posts.
		///		Moreover the result hasn't the tracking system enabled
		/// </remarks>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<PostDto> GetCompleteListOfPostDtos ( int pageIndex, int pageSize );

		///<summary>
		///	Return a list approved posts, sorted by publish date.
		///</summary>
		///<param name = "numberOfItems">The number of items.</param>
		///<returns>
		///	Return a list of <see cref="Post"/>.
		///	The return item could be null if there isn't items into the repository.
		///</returns>
		IEnumerable<Post> GetRecent ( int numberOfItems );

		///<summary>
		///	Return a list approved posts, sorted by publish date.
		///</summary>
		///<param name = "numberOfItems">The number of items.</param>
		///<returns>
		///	Return a list of <see cref="Post"/>.
		///	The return item could be null if there isn't items into the repository.
		///</returns>
		IList<PostDto> GetRecentPostDto ( int numberOfItems );

		///<summary>
		///	Return a list of posts for a specified month.
		///</summary>
		///<param name = "month">The id of the month (1 for january, 2 for february, etc).</param>
		///<param name = "year">The year (2010, 1978, etc).</param>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<Post> GetByMonth ( int month, int year, int pageIndex, int pageSize );

		///<summary>
		///	Return a list of posts for a specified month.
		///</summary>
		///<param name = "month">The id of the month (1 for january, 2 for february, etc).</param>
		///<param name = "year">The year (2010, 1978, etc).</param>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<PostDto> GetPostDtoByMonth ( int month, int year, int pageIndex, int pageSize );

		///<summary>
		///	Retrieve a paged list of approved posts.
		///</summary>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<Post> GetPublished ( int pageIndex, int pageSize );

		///<summary>
		///	Retrieve a paged list of approved posts.
		///</summary>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		IPagedResult<PostDto> GetPublishedPostDto ( int pageIndex, int pageSize );

		///<summary>
		///	Retireve a paged list of <see cref="Post"/> filtered by the specified <see cref="Category"/>.
		///</summary>
		/// <remarks>
		///		The result will include only published past posts, unpublished and future will be excluded from the result.
		///		Moreover the result hasn't the tracking system enabled
		/// </remarks>
		///<param name="category">The filter category.</param>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		/// <exception cref="ArgumentNullException"> If <paramref name="category"/> is null.</exception>
		IPagedResult<Post> GetPostsByCategory ( Category category, int pageIndex, int pageSize );

		///<summary>
		///	Retireve a paged list of <see cref="PostDto"/> filtered by the specified <see cref="CategoryDto"/>.
		///</summary>
		/// <remarks>
		///		The result will include only published past posts, unpublished and future will be excluded from the result.
		///		Moreover the result hasn't the tracking system enabled
		/// </remarks>
		///<param name="category">The filter category.</param>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		/// <exception cref="ArgumentNullException"> If <paramref name="category"/> is null.</exception>
		IPagedResult<PostDto> GetPostsDtoByCategory ( CategoryDto category, int pageIndex, int pageSize );

		///<summary>
		///	Retireve a paged list of unapproved posts.
		///</summary>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<param name="includeFuturesPosts">if set to <c>true</c> the result will include the futures posts.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		IPagedResult<Post> GetUnpublished ( int pageIndex, int pageSize, bool includeFuturesPosts );

		///<summary>
		///	Retireve a paged list of unapproved posts.
		///</summary>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<param name="includeFuturesPosts">if set to <c>true</c> the result will include the futures posts.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		IPagedResult<PostDto> GetUnpublishedPostDto ( int pageIndex, int pageSize, bool includeFuturesPosts );

		/// <summary>
		/// Retireve a paged list of unapproved posts with <see cref="Item.PublishDate"/> equal to <paramref name="date"/>.
		/// </summary>
		/// <param name="pageIndex">Index of the page (0 based).</param>
		/// <param name="pageSize">The number of items to retrieve.</param>
		/// <param name="date">The date.</param>
		/// <returns>
		/// An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.
		/// </returns>
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		IPagedResult<Post> GetUnpublishedForTheSpecifiedDate ( int pageIndex, int pageSize, DateTime date );

		/// <summary>
		/// Retireve a paged list of unapproved posts with <see cref="Item.PublishDate"/> equal to <paramref name="date"/>.
		/// </summary>
		/// <param name="pageIndex">Index of the page (0 based).</param>
		/// <param name="pageSize">The number of items to retrieve.</param>
		/// <param name="date">The date.</param>
		/// <returns>
		/// An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.
		/// </returns>
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		IPagedResult<PostDto> GetUnpublishedPostDtoForTheSpecifiedDate ( int pageIndex, int pageSize, DateTime date );

		/// <summary>
		/// Retireve a paged list of approved posts with <see cref="Item.PublishDate"/> greater then <paramref name="startDate"/> and lesser then <paramref name="endDate"/>.
		/// </summary>
		/// <param name="pageIndex">Index of the page (0 based).</param>
		/// <param name="pageSize">The number of items to retrieve.</param>
		/// <param name="startDate">The start date.</param>
		/// <param name="endDate">The end date.</param>
		/// <returns>
		/// An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.
		/// </returns>
		IPagedResult<Post> GetPublishedPostForSpecifiedPublishDateRange ( int pageIndex, int pageSize, DateTime startDate, DateTime endDate );

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetUnpublishedForTheSpecifiedDate(int,int,DateTime,bool)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsUnpublishedForSpecifiedDayRetrieved;

		/// <summary>
		/// This event will raise after a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetUnpublishedForTheSpecifiedDate(int,int,DateTime,bool)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Tuple<int, int, DateTime, bool>>> PostsUnpublishedForSpecifiedDayRetrieving;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetUnpublished(int,int,bool,bool)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsUnpublishedRetrieved;

		/// <summary>
		/// This event will raise after a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetUnpublished(int,int,bool,bool)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Tuple<int, int,bool,bool>>> PostsUnpublishedRetrieving;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetPublishedPostWithCommentsDisabled(int,int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsWithCommentsEnabledRetrieved;

		/// <summary>
		/// This event will raise after a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetPublishedPostWithCommentsDisabled(int,int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Tuple<int, int>>> PostsWithCommentsEnabledRetrieving;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetPostsByCategory(Category,int,int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsRetrievedByCategory;

		/// <summary>
		/// This event will raise after a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetPostsByCategory(Category,int,int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Tuple<Category, int, int>>> PostsRetrievingByCategory;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetRelatedContent(Post, int, int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Tuple<Post, int, int>>> PostsRetrievingByRelated;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetRelatedContent(Post, int, int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsRetrievedByRelated;

		/// <summary>
		/// This event will raise before a list of <see cref="Month"/> will be retrieved by the implementation of <see cref="GetMonths()"/>.
		/// </summary>
		event EventHandler<CancelEventArgs> MonthRetrieving;

		/// <summary>
		/// This event will raise when a list of <see cref="Month"/> will be retrieved by the implementation of <see cref="GetMonths()"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IList<Month>>> MonthRetrieved;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will beretrieved by the implementation of <see cref="GetRecent(int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgs> PostsRecentRetrieving;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetRecent(int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgsWithOneParameter<IEnumerable<Post>, int>> PostsRecentRetrieved;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetBySlug(string)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<string>> PostRetrievingBySlug;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetBySlug(string)"/>.
		/// </summary>
		event EventHandler<GenericEventArgsWithOneParameter<Post,string >> PostRetrievedBySlug;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetByKey(int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<int>> PostRetrievingByKey;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetByKey(int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgsWithOneParameter<Post, int>> PostRetrievedByKey;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetByMonth(int,int, int,int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Tuple<int, int>>> PostsRetrievingByMonth;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetByMonth(int,int, int,int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgsWithOneParameter<IPagedResult<Post>, Tuple<int, int>>> PostsRetrievedByMonth;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetPublished(int,int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgs> PostsPublishedRetrieving;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetPublished(int,int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsPublishedRetrieved;

		/// <summary>
		/// This event will raise before a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetCompleteList(int,int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgs> PostsRetrieving;

		/// <summary>
		/// This event will raise when a list of <see cref="Post"/> will be retrieved by the implementation of <see cref="GetCompleteList(int,int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<IPagedResult<Post>>> PostsRetrieved;

		/// <summary>
		/// This event will raise before a <see cref="Post"/> will be deleted by the implementation of <see cref="Delete(int)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<int>> PostDeleting;

		/// <summary>
		/// This event will raise after a <see cref="Post"/> will be deleted by the implementation of <see cref="Delete(int)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<Post>> PostDeleted;

		/// <summary>
		/// This event will raise before a <see cref="Post"/> will be saved by the implementation of <see cref="Save(Post)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Post>> PostSaving;

		/// <summary>
		/// This event will raise after a <see cref="Post"/> will be saved by the implementation of <see cref="Save(Post)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<Post>> PostSaved;

		/// <summary>
		/// This event will raise before a <see cref="Post"/> will be saved by the implementation of <see cref="Update(Post)"/>.
		/// </summary>
		event EventHandler<CancelEventArgsWithOneParameter<Post>> PostUpdating;

		/// <summary>
		/// This event will raise after a <see cref="Post"/> will be saved by the implementation of <see cref="Update(Post)"/>.
		/// </summary>
		event EventHandler<GenericEventArgs<Post>> PostUpdated;
	}
}
